package ws.cmpe451.group7.ourcity.webservice;

import java.io.IOException;
import java.io.PrintWriter;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.JSONException;

import ws.cmpe451.group7.ourcity.webservice.exception.GeneralIllegalArgumentException;
import cmpe451.group7.ourcity.recommendation.RecommendationException;
import cmpe451.group7.ourcity.util.Utils;

public class ControllerWrapper {

	/**
	 * A generic controller handler is written for better request parameter
	 * checking and exception handling
	 * 
	 * @param request
	 * @param response
	 * @param func
	 * @param requiredParameters
	 * @throws IOException
	 */
	public static void wrapMethod(HttpServletRequest request,
			HttpServletResponse response, Callable func,
			List<String> requiredParameters) throws IOException {
		/*
		 * This call returns a JSON object with the result set coming from DAO
		 * object
		 */
		response.setContentType("application/json");
		PrintWriter responseWriter = response.getWriter();
		Map<String, String[]> parameters = request.getParameterMap();
		Set<String> keys = parameters.keySet();

		try {
			/*
			 * If the request contains only all, return all places
			 */
			if (!(Utils.exactMatch(keys, requiredParameters) && Utils
					.hasOneParameter(parameters))) {
				throw new GeneralIllegalArgumentException("Unsupported action");
			}

			func.call(request, response, responseWriter, parameters);

		} catch (GeneralIllegalArgumentException e) {
			// request contains illegal parameter
			responseWriter.printf("{\"success\":0, \"error\":\"%s\"}",
					e.getMessage());
		} catch (NumberFormatException e) {
			responseWriter
					.print("{\"success\":0, \"error\":\"Number format exception\"}");
		} catch (InvalidKeyException | NoSuchPaddingException
				| IllegalBlockSizeException | BadPaddingException
				| NoSuchAlgorithmException | InvalidKeySpecException e) {
			responseWriter.printf("{\"success\":0, \"error\":\"%s\"}",
					"Password error");
		} catch (JSONException e) {
			responseWriter.printf("{\"success\":0, \"error\":\"%s\"}",
					"Error occured while converting result into JSON object");
		} catch (RecommendationException | IllegalStateException
				| ServletException e) {
			responseWriter.printf("{\"success\":0, \"error\":\"%s\"}",
					e.getMessage());
		}

		responseWriter.close();
	}

}